﻿using UnityEngine;
using System.Collections.Generic;

public class GameManager : MonoBehaviour
{  
    public GUISkin ss;

    public static GameManager gamemanager;

    public Texture qiang;
    public Texture caodi;
    public Texture snakebody1;
    public Texture snakebody2;
    public Texture chi;
    public Texture fan;
    public Texture jian;
    public Texture luan;
    public Texture shi;
    public Texture shu;
    public Texture ting;
    public Texture you;
    public Texture zuo;
    public Texture snakeHead;
    public Texture snakeright;
    public Texture snakedown;
    public Texture snakeleft;

    bool bStarting;
    bool bGameOver;
    bool bPause;
    public int score1 = 0;
    public int score2 = 0;
    [HideInInspector]
    public float textTime = 1.0f;
    public string myText = "";

    public List<List<Grid>> lGrid = new List<List<Grid>>();
    public List<SnakeGrid> lSnakeGrid1 = new List<SnakeGrid>();
    public List<SnakeGrid> lSnakeGrid2 = new List<SnakeGrid>();
    System.Random rdm = new System.Random();
    public Snake snake1 = new Snake();
    public Snake snake2 = new Snake();
    float nextGoodsTime;
    const float t = 10;
    public int dir1 = 1;
    public int dir2 = 1;

    public float gameTimer = 180.0f;

    public List<FoodGrid> lFoodGrid = new List<FoodGrid>();

    Vector2 phonePosition;

    //加速度的持续时间
    public float foodNumTime1 = 5f;
    public float foodNumTime2 = 5f;

    //标志是否可以连击加速
    public bool speedCombo1 = false;
    public bool speedCombo2 = false;

    private bool isSingle;

    void Awake()    
    {
        gamemanager = this;
    }

    void Start()
    {
        nextGoodsTime = Time.time + 5;
        
    }
 
    /// <summary>
    /// 初始化地图
    /// </summary>
    private void ResetGrid()
    {
        //清空之前的地图
        lGrid.Clear();
        lSnakeGrid1.Clear();
        lSnakeGrid2.Clear();
        lFoodGrid.Clear();
        score1 = 0;
        score2 = 0;
        nextGoodsTime = Time.time + 5;
        myText = "";
        foodNumTime1 = 5f;
        foodNumTime2 = 5f;
        snake1.foodNum = 0;
        snake2.foodNum = 0;
        snake1.moveSep = 0.3f;
        snake2.moveSep = 0.3f;

        //构建地图
        int r = Screen.width / Grid.isize - 2;
        int c = Screen.height / Grid.isize - 2;
        for (int i = 0; i < r; i++)
        {
            lGrid.Add(new List<Grid>());
            for (int j = 0; j < c; j++)
            {
                if (i == 0 || j == 0 || i == r - 1 || j == c - 1)
                {
                    WallGrid wg = new WallGrid();
                    wg.ix = i;
                    wg.iy = j;
                    lGrid[i].Add(wg);
                }
                else
                {
                    EmptyGrid eg = new EmptyGrid();
                    eg.ix = i;
                    eg.iy = j;
                    lGrid[i].Add(eg);
                }
            }
        }

        //构建蛇1的初始长度
        snake1.CreatSnake(20, lSnakeGrid1, lGrid, "1");

        //构建蛇2的初始长度
        snake2.CreatSnake(5, lSnakeGrid2, lGrid, "2");

        //随机食物
        RandomOneFood();

        snake1.gameOver = false;
        snake2.gameOver = false;
        bGameOver = false;

        gameTimer = 180.0f;
    }

    void RandomOneFood()
    {
        while (true)
        {
            int x = rdm.Next(lGrid.Count);
            int y = rdm.Next(lGrid[x].Count);
            if (lGrid[x][y] is EmptyGrid)
            {
                FoodGrid foodGrid = new FoodGrid();
                lFoodGrid.Add(foodGrid);
                foodGrid.ix = x;
                foodGrid.iy = y;
                lGrid[x][y] = foodGrid;
                break;
            }
        }
    }

    void OnGUI()
    {
        GUI.skin = ss;
        for (int i = 0; i < lGrid.Count; i++)
        {
            for (int j = 0; j < lGrid[i].Count; j++)
            {
                lGrid[i][j].Showme();
            }
        }
        if (lSnakeGrid1.Count > 0 && lSnakeGrid2.Count > 0) 
        {
            if (snake1.iDirectX == 0 && snake1.iDirectY == -1)
            {
                lSnakeGrid1[0].ShowHead(snakeHead);
            }
            else if (snake1.iDirectX == 0 && snake1.iDirectY == 1)
            {
                lSnakeGrid1[0].ShowHead(snakedown);
            }
            else if (snake1.iDirectX == -1 && snake1.iDirectY == 0)
            {
                lSnakeGrid1[0].ShowHead(snakeleft);
            }
            else if (snake1.iDirectX == 1 && snake1.iDirectY == 0)
            {
                lSnakeGrid1[0].ShowHead(snakeright);
            }

            if (snake2.iDirectX == 0 && snake2.iDirectY == -1)
            {
                lSnakeGrid2[0].ShowHead(snakeHead);
            }
            else if (snake2.iDirectX == 0 && snake2.iDirectY == 1)
            {
                lSnakeGrid2[0].ShowHead(snakedown);
            }
            else if (snake2.iDirectX == -1 && snake2.iDirectY == 0)
            {
                lSnakeGrid2[0].ShowHead(snakeleft);
            }
            else if (snake2.iDirectX == 1 && snake2.iDirectY == 0)
            {
                lSnakeGrid2[0].ShowHead(snakeright);
            }
        }
        GUIStyle gs = new GUIStyle();
        gs.fontSize = 40;
        gs.normal.textColor = Color.green;
        if (snake1.gameOver) 
        {
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 200, 200, 200), "你的得分:" + lSnakeGrid1.Count, gs);
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 150, 200, 200), "电脑得分:" + lSnakeGrid2.Count, gs);
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200), "电脑胜利", gs);
        }

        if (snake2.gameOver)
        {
            GUI.Label(new Rect(Screen.width / 2, Screen.height / 2 - 200, 200, 200), "你的得分:" + lSnakeGrid1.Count, gs);
            GUI.Label(new Rect(Screen.width / 2, Screen.height / 2 - 150, 200, 200), "电脑得分:" + lSnakeGrid2.Count, gs);
            GUI.Label(new Rect(Screen.width / 2, Screen.height / 2 - 100, 200, 200), "玩家胜利", gs);
        }

        if (bGameOver)
        {
            //if (GUI.Button(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 50, 300, 100), "Restart"))
            //{
            //    ResetGrid();
            //    snake1.moveSep = 0.3f;
            //    snake2.moveSep = 0.3f;
            //    bStarting = true;
            //}
            if (GUI.Button(new Rect(Screen.width / 2 - 150, Screen.height / 2 + 100, 300, 100), "Quit"))
            {
                Application.Quit();
            }
        }

        if (!bStarting)
        {
            if (GUI.Button(new Rect(Screen.width / 2 - 350, Screen.height / 2 - 50, 300, 100), "打电脑"))
            {
                ResetGrid();
                bStarting = true;
                isSingle = true;              
            }
            if (GUI.Button(new Rect(Screen.width / 2 + 50, Screen.height / 2 - 50, 300, 100), "双人对打"))
            {
                ResetGrid();
                bStarting = true;
                isSingle = false;
            }
        }

        if (bPause)
        {
            if (GUI.Button(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 50, 300, 100), "Continue"))
            {
                bPause = false;
            }
            if (GUI.Button(new Rect(Screen.width / 2 - 150, Screen.height / 2 + 100, 300, 100), "Quit"))
            {
                Application.Quit();
            }
        }
        //GUI.Label(new Rect(10, 0, 200, 200), "你的身体数量： " + lSnakeGrid1.Count, gs);
        
        if (gameTimer >= 0 && bStarting) 
        {
            GUI.Label(new Rect(Screen.width / 2 - 20, 0, 200, 200), lSnakeGrid1.Count + ":" + lSnakeGrid2.Count, gs);
            GUI.Label(new Rect(Screen.width / 2 - 20, 50, 200, 200), gameTimer.ToString(), gs);
            GUI.Label(new Rect(10, 0, 200, 200), "黄蛇：" + snake1.foodNum.ToString(), gs);
            GUI.Label(new Rect(Screen.width - 150, 0, 200, 200), "红蛇：" + snake2.foodNum.ToString(), gs);
        }

        //if (phonePosition != null && lSnakeGrid1.Count != 0) 
        //{
        //    GUI.Label(new Rect(Screen.width / 2 - 20, 100, 200, 200), phonePosition.x + "    " + phonePosition.y, gs);
        //    GUI.Label(new Rect(Screen.width / 2 - 20, 200, 200, 200), lSnakeGrid1[0].px + "     " + lSnakeGrid1[0].py, gs);
        //}


        gs.normal.textColor = new Color(1, 235 / 255f, 4 / 255f, textTime);
        GUI.Label(new Rect(Screen.width / 2 - 80, Screen.height / 2 - 350, 500, 100), myText, gs);
        
    }

    /// <summary>
    /// 随机刷新食物
    /// </summary>
    void Randomitem()
    {
        if (Time.time <= nextGoodsTime)
            return;
        nextGoodsTime = Time.time + t;
        int i = rdm.Next(9);
        //int i = 4;
        switch (i)
        {
        case 0:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    StopFood sf = new StopFood();
                    sf.ix = x;
                    sf.iy = y;
                    lGrid[x][y] = sf;
                    lFoodGrid.Add(sf);
                    break;
                }
            }
            break;
        case 1:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    LeftFood lf = new LeftFood();
                    lf.ix = x;
                    lf.iy = y;
                    lGrid[x][y] = lf;
                    lFoodGrid.Add(lf);
                    break;
                }
            }
            break;
        case 2:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    RightFood rf = new RightFood();
                    rf.ix = x;
                    rf.iy = y;
                    lGrid[x][y] = rf;
                    lFoodGrid.Add(rf);
                    break;
                }
            }
            break;
        case 3:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    RandomPos rp = new RandomPos();
                    rp.ix = x;
                    rp.iy = y;
                    lGrid[x][y] = rp;
                    lFoodGrid.Add(rp);
                    break;
                }
            }
            break;
        case 4:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    WrongDirector wd = new WrongDirector();
                    wd.ix = x;
                    wd.iy = y;
                    lGrid[x][y] = wd;
                    lFoodGrid.Add(wd);
                    break;
                }
            }
            break;
        case 5:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    EndSwaps es = new EndSwaps();
                    es.ix = x;
                    es.iy = y;
                    lGrid[x][y] = es;
                    lFoodGrid.Add(es);
                    break;
                }
            }
            break;
        case 6:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    FoodGrid fd = new FoodGrid();
                    fd.ix = x;
                    fd.iy = y;
                    lGrid[x][y] = fd;
                    lFoodGrid.Add(fd);
                    break;
                }
            }
            break;
        case 7:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    SpeedFood sf = new SpeedFood();
                    sf.ix = x;
                    sf.iy = y;
                    lGrid[x][y] = sf;
                    lFoodGrid.Add(sf);
                    break;
                }
            }
            break;
        case 8:
            while (true)
            {
                int x = rdm.Next(lGrid.Count);
                int y = rdm.Next(lGrid[x].Count);
                if (lGrid[x][y] is EmptyGrid)
                {
                    TimeFood tf = new TimeFood();
                    tf.ix = x;
                    tf.iy = y;
                    lGrid[x][y] = tf;
                    lFoodGrid.Add(tf);
                    break;
                }
            }
            break;
        }
    }

    /// <summary>
    /// 操作控制
    /// </summary>
    public void Control()
    {
        //玩家1触摸输入
        if (snake1.bDirectionLock)
            return;
        
        //Touch touch;
        //int i = 0;

        //while (i < Input.touchCount)
        //{
        //    touch = Input.GetTouch(i);
        //    if (touch.phase == TouchPhase.Began)
        //    {
        //        int my = (int)(Screen.height - touch.position.y);
        //        phonePosition.x = touch.position.x;
        //        phonePosition.y = my;
                
               
        //        if (snake1.iDirectY == 0)
        //        {
        //            snake1.iDirectX = 0;
        //            snake1.iDirectY = (my < lSnakeGrid1[0].py ? -1 : 1) * dir1;
        //            snake1.bDirectionLock = true;
                    
        //        }
        //        else if (snake1.iDirectX == 0)
        //        {
        //            snake1.iDirectX = (touch.position.x < lSnakeGrid1[0].px ? -1 : 1) * dir1;
        //            snake1.iDirectY = 0;
        //            snake1.bDirectionLock = true;
        //        }
        //    }
        //    ++i;
        //}

        //玩家鼠标操作
        if (Input.GetMouseButtonDown(0))
        {
            int my = (int)(Screen.height - Input.mousePosition.y);
            Debug.Log("mouse=" + Input.mousePosition.x + "   " + Input.mousePosition.y + "   my=" + my);
            Debug.Log("snake=" + lSnakeGrid1[0].px + "   " + lSnakeGrid1[0].py);

            if (snake1.iDirectY == 0)
            {
                //Debug.Log("up");
                snake1.iDirectX = 0;
                snake1.iDirectY = (my < lSnakeGrid1[0].py ? -1 : 1) * dir1;
                snake1.bDirectionLock = true;
            }
            else if (snake1.iDirectX == 0)
            {
                //Debug.Log("up");
                snake1.iDirectX = (Input.mousePosition.x < lSnakeGrid1[0].px ? -1 : 1) * dir1;
                snake1.iDirectY = 0;
                snake1.bDirectionLock = true;
            }

        }

        //玩家键盘输入控制
        if (Input.GetKeyDown(KeyCode.UpArrow) && snake1.iDirectY == 0)
        {
            //Debug.Log("up");
            snake1.iDirectX = 0;
            snake1.iDirectY = -1 * dir1;
            //snake1.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.DownArrow) && snake1.iDirectY == 0)
        {
            //Debug.Log("down");
            snake1.iDirectX = 0;
            snake1.iDirectY = 1 * dir1;
            //snake1.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.LeftArrow) && snake1.iDirectX == 0)
        {
            //Debug.Log("left");
            snake1.iDirectX = -1 * dir1;
            snake1.iDirectY = 0;
            //snake1.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.RightArrow) && snake1.iDirectX == 0)
        {
            //Debug.Log("right");
            snake1.iDirectX = 1 * dir1;
            snake1.iDirectY = 0;
            //snake1.bDirectionLock = true;
        }
        //输入控制2
        if (Input.GetKeyDown(KeyCode.W) && snake2.iDirectY == 0)
        {
            //Debug.Log("w");
            snake2.iDirectX = 0;
            snake2.iDirectY = -1 * dir2;
            //snake2.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.S) && snake2.iDirectY == 0)
        {
            //Debug.Log("d");
            snake2.iDirectX = 0;
            snake2.iDirectY = 1 * dir2;
            //snake2.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.A) && snake2.iDirectX == 0)
        {
            //Debug.Log("left");
            snake2.iDirectX = -1 * dir2;
            snake2.iDirectY = 0;
            //snake2.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.D) && snake2.iDirectX == 0)
        {
            //Debug.Log("right");
            snake2.iDirectX = 1 * dir2;
            snake2.iDirectY = 0;
            //snake2.bDirectionLock = true;
        }
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (bGameOver)
            {
                bGameOver = false;
                ResetGrid();
            }
            else if (!bStarting)
            {
                bStarting = true;
                ResetGrid();
            }
            else
            {
                bPause = !bPause;
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        textTime -= Time.deltaTime/2;
        
        if (bStarting)
            gameTimer -= Time.deltaTime;

        bGameOver = snake1.gameOver || snake2.gameOver;
        if (bGameOver)
        {
            bStarting = false;
            return;
        }
        if (!bStarting)
        {
            return;
        }

        if (gameTimer <= 0) 
        {
            if (lSnakeGrid1.Count >= lSnakeGrid2.Count)
                snake2.gameOver = true;
            else
                snake1.gameOver = true;
        }


        Control();

        //蛇变为〇则输了
        if (lSnakeGrid1.Count == 0)
        {
            snake1.gameOver = true;
        }
        if (lSnakeGrid2.Count == 0)
        {
            snake2.gameOver = true;
        }

        //暂停控制
        if (bPause) { return; }

        Randomitem();

        snake1.Move(lSnakeGrid1, lSnakeGrid2, lGrid, "1", Vector2.zero);
        if (snake1.eat)
        {
            RandomOneFood();
            snake1.eat = false;
        }

        if (isSingle)
        {
            AStar ai = new AStar();
            Vector2 v1 = new Vector2();
            v1.x = lSnakeGrid2[0].ix;
            v1.y = lSnakeGrid2[0].iy;

            //Vector2 v2 = new Vector2();
            //v2.x = lFoodGrid[0].ix;
            //v2.y = lFoodGrid[0].iy;

            if (snake2.moveSep >= 0.3f)
            {
                ai.FindPath(v1, Choosefood());
            }
            else
            {
                ai.FindPath(v1, SnankTail());
                Debug.Log(ai.path.Count);
            }

            if (ai.path.Count > 1)
            {
                //Debug.LogError("没进来");
                snake2.Move(lSnakeGrid2, lSnakeGrid1, lGrid, "2", ai.path[1].Position);
            }
        }
        else
        {
            snake2.Move(lSnakeGrid2, lSnakeGrid1, lGrid, "2", Vector2.zero);  
        }

  
        if (snake2.eat)
        {
            RandomOneFood();
            snake2.eat = false;
        }

        if (dir1 < 0 && Time.time > snake1.fxOverTime)
            dir1 = 1;
        if (dir2 < 0 && Time.time > snake2.fxOverTime)
            dir2 = 1;

        //当食物数量大于5的时候，开始加速，并且开始倒计时。
        if (snake1.foodNum >= 5)
        {
            foodNumTime1 -= Time.deltaTime;
            //speedCombo1 = true;
        }
        if (snake2.foodNum >= 5)
        {
            foodNumTime2 -= Time.deltaTime;
            //speedCombo2 = true;
        }

        //倒计时为0时，食物数量清零，并且结束加速
        if (foodNumTime1 < 0)
        {
            foodNumTime1 = 5f;
            snake1.foodNum = 0;
            //speedCombo1 = false;
            snake1.moveSep = 0.3f;

        }
        if (foodNumTime2 < 0)
        {
            foodNumTime2 = 5f;
            snake2.foodNum = 0;
            //speedCombo2 = false;
            snake2.moveSep = 0.3f;
        }

    }

    //选择一个最近的食物
    private Vector2 Choosefood() {
        int min=int.MaxValue;
        Vector2 target = new Vector2();
        int snakeX=lSnakeGrid2[0].ix;
        int snakeY=lSnakeGrid2[0].iy;
        foreach (FoodGrid f in lFoodGrid)
        {
            int value=Mathf.Abs(f.ix-snakeX)+Mathf.Abs(f.iy-snakeY);
            if (value < min)
            {
                min = value;
                target.x = f.ix;
                target.y = f.iy;
            }
        }
        return target;
    }

    private Vector2 SnankTail()
    {
        Vector2 Vsnake1 = new Vector2();
        Vsnake1.x = lSnakeGrid1[lSnakeGrid1.Count - 1].ix;
        Vsnake1.y = lSnakeGrid1[lSnakeGrid1.Count - 1].iy;

        return Vsnake1;
    }
}
